from django.shortcuts import render,redirect
from django.urls import reverse

from backend.users.models import GroupSetting
from backend.cews.models import RepairOrderTask, Parts, TaskGroup, RepairOrder, QRMapLocation
from backend.eform.models import Eform
from backend.eform.views import createEform
from utils.decorators import request_data_view
from rest_framework.authtoken.models import Token
from django.contrib.auth import login
from django.views.decorators.csrf import csrf_exempt
import json
import qrcode
from qrcode.image.styledpil import StyledPilImage
import qrcode.image.svg

import os
from io import BytesIO
from django.templatetags.static import static
import base64
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
from django.http import HttpResponse
from django.shortcuts import render
from config.settings.base import STATICFILES_DIRS

from django.utils import timezone

# Create your views here.

# @request_data_view(keys=['repair_order_task_id'], request_attr='GET')
@csrf_exempt
def repair_order_task_eform_view(request,repair_order_task_id):
    '''
        check if eform exist for this task and redirect user to eform edit page
    '''
    ## help login 
    token = request.POST.get('token',None)
    user = None
    try:
        token = Token.objects.get(key=token)
        user = token.user
        
    except:
        print(token)
        print('token not found')
        token = None
        print(request.user)
        if not request.user.is_authenticated:
            return redirect(reverse('account_login')+'?next='+request.path)
    finally:
        if user:
            login(request,user,backend='allauth.account.auth_backends.AuthenticationBackend')
            request.user = user
        else:
            if not request.user.is_authenticated:
                return redirect(reverse('account_login')+'?next='+request.path)
            
    
    rot = RepairOrderTask.objects.get(id=repair_order_task_id)

    if not rot.has_eform:
        raise Exception('This task has no eform')
    
    eform = Eform.objects.filter(id=rot.eform_id).first()

    # 验证未结束的判断
    flow=RepairOrderTask.FlowType.DONE
    if rot.done_by and (rot.verify_by == None):
        flow=RepairOrderTask.FlowType.VERIFY
    if rot.verify_by and (rot.endorse_by == None):
        flow=RepairOrderTask.FlowType.ENDORSE

    # 验证结束的判断
    if rot.role == RepairOrderTask.RoleType.TESTER and rot.done_by and rot.done_by_datetime:
        flow = RepairOrderTask.FlowType.DONE
    elif rot.role == RepairOrderTask.RoleType.CHECKER and rot.endorse_by and rot.endorse_by_datetime:
        flow = RepairOrderTask.FlowType.ENDORSE
    if eform and eform.doneDate != None:
        return redirect(reverse('eform:checkEform',kwargs={'pk':eform.id}) + "?role=" + rot.role + "&flow="+ flow)
    
    if not eform:
        eform = createEform(request,rot.eform_schema_id)
        eform.verifiedby_user_id = rot.verify_user_id
        eform.endorsedby_user_id = rot.endorse_user_id
        eform.create_user_id = rot.create_user_id

        eform.save()
        rot.eform_id = eform.id
        rot.save()
        print('createEform', rot)
        print('eform_schema_id', rot.eform_schema_id)


    has_permission, context = check_task_group(request, eform.eformSchema)

    if not has_permission:
        print(context)
        return render(request, 'noPermission.html', context)
    
    is_complete = False
  
    ro = RepairOrder.objects.get(pk=rot.repair_order.id)
    print('RepairOrder status',ro.status)

    if ro.status == RepairOrder.STATUS.COMPLETE or ro.status == RepairOrder.STATUS.FORCE_COMPLETE:
        is_complete = True
    print(is_complete)
    if is_complete:
        return redirect(reverse('eform:eformDisableView',kwargs={'pk':eform.id}))
    else:
        return redirect(reverse('eform:eformView',kwargs={'pk':eform.id}) + "?role=" + rot.role + "&flow="+ flow)

@csrf_exempt
def qrcode_view(request, part_id):
    print(request)
    print(part_id)
    # part = Parts.objects.get(pk=part_id)
    # return render(request,'qrcode.html',{'qrcode':json.dumps({"CAT":part.stock_code,"SN":part.serial_no})})

    part = Parts.objects.get(pk=part_id)
    qr_text = json.dumps({"CAT": part.stock_code,"SN": part.serial_no})
    text = f"SC: {part.stock_code},SN: {part.serial_no}"
    # sn_text = f"SN: {part.serial_no}"
    image_data = generate_qr_with_logo(qr_text, text)


    encoded_image = base64.b64encode(image_data).decode('utf-8')
    context = {
        'encoded_image': encoded_image,
        'SC' : part.stock_code,
        'SN' : part.serial_no,
        }
    return render(request, 'qrcode.html', context)

@csrf_exempt
def location_qrcode_view(request, id):
    print(request)
    print(id)
    # part = Parts.objects.get(pk=id)
    # return render(request,'qrcode.html',{'qrcode':json.dumps({"CAT":part.stock_code,"SN":part.serial_no})})

    qr_loc = QRMapLocation.objects.get(pk=id)
    qr_text = qr_loc.qr_string
    text = f"CAT: {qr_loc.category},SN: {qr_loc.train}"

    # sn_text = f"SN: {part.serial_no}"
    image_data = generate_qr_with_logo(qr_text, text)


    encoded_image = base64.b64encode(image_data).decode('utf-8')
    context = {
        'encoded_image': encoded_image,
        'CAT' : qr_loc.category,
        'SN' : qr_loc.train,
        }
    return render(request, 'location_qrcode.html', context)

def generate_qr_with_logo(qr_text, text):
    # Create a QR code instance
    qr = qrcode.QRCode(
        version=3,
        # error_correction=qrcode.constants.ERROR_CORRECT_Q,
        box_size=3,
        border=0,
    )

    # Add data to the QR code
    qr.add_data(qr_text)
    qr.make(fit=True)

    # Generate an image from the QR code
    qr_image = qr.make_image(fill_color="black", back_color="white")
    # qr_image = qr.make_image(back_color=(255, 195, 235), fill_color=(55, 95, 35))
    # print(STATICFILES_DIRS)
    # Load and resize the logo image
    logo_size = (24, 24)  # Adjust the size of the logo as needed
    logo = Image.open(f"{STATICFILES_DIRS[0]}/images/svgs/24.png")
    logo = logo.resize(logo_size)
    # print(logo)
    new_size = (90, 90) 
    resized_image = qr_image.resize(new_size)
    # print(resized_image)
    # Calculate the position to place the logo at the center of the QR code
    qr_width, qr_height = resized_image.size
    logo_width, logo_height = logo.size
 
    logo_position = ((qr_width - logo_width) // 2, (qr_height - logo_height) // 2)

    # Paste the logo onto the QR code image
    resized_image.paste(logo, logo_position)

    ## add text in img
    background = Image.new('RGBA', (192, 104), (255,255,255,255))
    draw = ImageDraw.Draw(background)

    arr = text.split(',')
    print(arr)
    count = 0
    for long_str in arr:
        for i in range(0, len(long_str), 13):
            chunk = long_str[i:i+13]
            # qrcode right
            # draw.text((0,5+count),chunk, (0,0,0))
            # qrcode left
            draw.text((100,5+count),chunk, (0,0,0))
            count += 10
   

    # draw.text((80,35),sn, (0,0,0))

    # qrcode right
    # background.paste(resized_image, (90,5))
    # qrcode left
    background.paste(resized_image, (5,5))

    # Create a buffer to hold the image data
    buffer = BytesIO()
 
    # Convert the image to bytes and save it to the buffer
    # qr_image.save(buffer, format='PNG')
    background.save(buffer, format='PNG')
    image_bytes = buffer.getvalue()

    # Set the buffer's position to the start
    buffer.seek(0)

    return image_bytes

# def generate_qr_with_logo(qr_text, text):
#     # Create a QR code instance
#     qr = qrcode.QRCode(
#         version=3,
#         error_correction=qrcode.constants.ERROR_CORRECT_H,
#         box_size=2,
#         border=0,
#     )

#     # Add data to the QR code
#     qr.add_data(qr_text)
#     qr.make(fit=True)

#     # Generate an image from the QR code
#     qr_image = qr.make_image(fill_color="black", back_color="white")
#     # qr_image = qr.make_image(back_color=(255, 195, 235), fill_color=(55, 95, 35))
#     print(STATICFILES_DIRS)
#     # Load and resize the logo image
#     logo_size = (18, 18)  # Adjust the size of the logo as needed
#     logo = Image.open(f"{STATICFILES_DIRS[0]}/images/svgs/24.png")
#     logo = logo.resize(logo_size)
#     print(logo)

#     # Calculate the position to place the logo at the center of the QR code
#     qr_width, qr_height = qr_image.size
#     logo_width, logo_height = logo.size
 
#     logo_position = ((qr_width - logo_width) // 2, (qr_height - logo_height) // 2)

#     # Paste the logo onto the QR code image
#     qr_image.paste(logo, logo_position)

#     ## add text in img
#     background = Image.new('RGBA', (255, 170), (255,255,170,170))
#     draw = ImageDraw.Draw(background)

#     arr = text.split(',')
#     print(arr)
#     count = 0
#     for long_str in arr:
#         for i in range(0, len(long_str), 12):
#             chunk = long_str[i:i+12]
#             draw.text((80,5+count),chunk, (0,0,0))
#             count += 10
   

#     # draw.text((80,35),sn, (0,0,0))
#     background.paste(qr_image, (0,0))
#     # Create a buffer to hold the image data
#     buffer = BytesIO()
 
#     # Convert the image to bytes and save it to the buffer
#     # qr_image.save(buffer, format='PNG')
#     background.save(buffer, format='PNG')
#     image_bytes = buffer.getvalue()

#     # Set the buffer's position to the start
#     buffer.seek(0)

#     return image_bytes

# @csrf_exempt
def eforms(request):

    token = request.POST.get('token',None)
    user = None
    try:
        token = Token.objects.get(key=token)
        user = token.user
        
    except:
        print(token)
        print('token not found')
        token = None
        print(request.user)
        if not request.user.is_authenticated:
            return redirect(reverse('account_login')+'?next='+request.path)
    finally:
        if user:
            login(request,user,backend='allauth.account.auth_backends.AuthenticationBackend')
            request.user = user
        else:
            if not request.user.is_authenticated:
                return redirect(reverse('account_login')+'?next='+request.path)

    return redirect(reverse('eform:list'))

def check_task_group(request, eformSchema):
    print(request.user, eformSchema)
    now = timezone.now()

    context = {
        'messages' : []
    }

    has_perm = False

    if request.user.is_superuser:
        return True, context

    for group in request.user.groups.all():

        if group.permissions.filter(codename='can_do_maintenance_task').exists():
            if GroupSetting.objects.filter(group=group, expiry_date__gt=now, enable=True).exists():
                task_group_dict = {
                    tg.eformSchema_id : tg
                    for tg in TaskGroup.objects.filter(group=group)
                }
                print(task_group_dict)
                print('eformSchema_id', eformSchema.id)
                if not eformSchema.id in task_group_dict:
                    context['messages'].append(f"Insufficient permission in group: ''{group}'': title: {eformSchema.title}, form no.: {eformSchema.formNo}")
                else:
                    has_perm = True
                    context['messages'] = []
                    break 
            else:
                context['messages'].append(f"Insufficient permission, group: {group} is expiry")
        else:
            context['messages'].append(f"Insufficient permission user not in any groups")
        print(context['messages'])
        
    if len(context['messages'])>0 and has_perm is False:
        return has_perm, context
    return has_perm, context